package com.softserveinc.interactive_board.dao;

import java.util.List;

import org.hibernate.SessionFactory;
import org.hibernate.classic.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;

import com.softserveinc.interactive_board.domain.Presentation;
import com.softserveinc.interactive_board.domain.User;
import com.softserveinc.interactive_board.domain.UserType;

@Repository
public class UserDAOImpl implements UserDAO {

	public List<UserType> getUserTypes() {
		return sessionFactory.getCurrentSession().createQuery("from UserType")
				.list();
	}

	public List<UserType> getRegistratebleUserTypes() {
		return sessionFactory.getCurrentSession()
				.createQuery("from UserType u where u.id < 3").list();
	}

	public List<User> getUsers() {
		return sessionFactory.getCurrentSession()
				.createQuery("from User u order by u.id").list();
	}

	public List<User> getUsersByType(int typeId) {
		return sessionFactory
				.getCurrentSession()
				.createQuery(
						"from User u where u.userType.id = :id order by u.id")
				.setString("id", String.valueOf(typeId)).list();
	}

	public User getUser(User user) {
		List<User> list = this.sessionFactory.getCurrentSession()
				.createQuery("from User u where u.id = :id")
				.setString("id", user.getId().toString()).list();
		if (list.isEmpty())
			return null;
		else
			return list.get(0);
	}

	public User getUser(Long id) {
		return this.getUser(new User(id));
	}

	public User getUser(String login) {
		List<User> list = this.sessionFactory.getCurrentSession()
				.createQuery("from User u where u.login = :login")
				.setString("login", login).list();
		if (list.isEmpty())
			return null;
		else
			return list.get(0);
	}

	public boolean addUser(User user) {
		if (!sessionFactory.getCurrentSession()
				.createQuery("from User u where u.login = :l")
				.setString("l", user.getLogin()).list().isEmpty())
			return false;
		sessionFactory.getCurrentSession().save(user);
		return true;
	}

	public boolean updateUser(User user) {
		Session session = this.sessionFactory.getCurrentSession();
		session.beginTransaction();
		List<User> list = session
				.createQuery("from User u where u.login = :login")
				.setString("login", user.getLogin()).list();
		if ((!list.isEmpty()) && (!(list.get(0)).getId().equals(user.getId())))
			return false;
		session.clear();
		User buff = (User) session.createQuery("from User u where u.id = :id")
				.setString("id", user.getId().toString()).list().get(0);
		if (buff.getUserType().getId().equals(Integer.valueOf(UserType.ID_PRESENTOR))
				&& (!user.getUserType().getId()
						.equals(Integer.valueOf(UserType.ID_PRESENTOR)))) {
			session.clear();
			List<Presentation> presList = session
					.createQuery("from Presentation p where p.user.id = :id")
					.setString("id", buff.getId().toString()).list();
			if (!presList.isEmpty())
				for (Presentation p : presList) {
					session.delete(p);
					session.flush();
				}
		}
		session.clear();
		session.update(user);
		session.flush();
		return true;
	}

	public void deleteUser(Long userId) {
		Session session = this.sessionFactory.getCurrentSession();
		session.beginTransaction();
		List<Presentation> list = session
				.createQuery("from Presentation p where p.user.id = :id")
				.setString("id", userId.toString()).list();
		session.clear();
		if (!list.isEmpty())
			for (Presentation p : list) {
				session.delete(p);
				session.flush();
			}
		session.delete(new User(userId));
		session.flush();
	}

	public void deleteUsers(List<User> list) {
		for (User u : list)
			this.sessionFactory.getCurrentSession().delete(new User(u.getId()));
	}

	private SessionFactory sessionFactory;

	@Autowired
	@Qualifier("sessionFactory")
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}
}
